package com.clinbrain;

import com.facebook.presto.spi.function.Description;
import com.facebook.presto.spi.function.ScalarFunction;
import com.facebook.presto.spi.function.SqlNullable;
import com.facebook.presto.spi.function.SqlType;
import com.facebook.presto.spi.type.StandardTypes;
import io.airlift.slice.Slice;
import io.airlift.slice.Slices;

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

public class CacheDateTimeConvert {

    private static DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    private static DateTimeFormatter DATE_FORMAT_1 = DateTimeFormatter.ofPattern("yyyy.MM.dd");
    private static DateTimeFormatter DATE_FORMAT_2 = DateTimeFormatter.ofPattern("yyyy.M.dd");
    private static DateTimeFormatter DATE_FORMAT_3 = DateTimeFormatter.ofPattern("yyyy.M.d");
    private static DateTimeFormatter DATE_FORMAT_4 = DateTimeFormatter.ofPattern("yyyy.MM.d");
    private static DateTimeFormatter TIME_FORMAT = DateTimeFormatter.ofPattern("HH:mm:ss");
    private static DateTimeFormatter TIME_FORMAT_1 = DateTimeFormatter.ofPattern("HH:mm:s");
    private static DateTimeFormatter TIME_FORMAT_2 = DateTimeFormatter.ofPattern("HH:m:ss");
    private static DateTimeFormatter TIME_FORMAT_3 = DateTimeFormatter.ofPattern("HH:m:s");
    private static DateTimeFormatter TIME_FORMAT_4 = DateTimeFormatter.ofPattern("H:mm:ss");
    private static DateTimeFormatter TIME_FORMAT_5 = DateTimeFormatter.ofPattern("H:mm:s");
    private static DateTimeFormatter TIME_FORMAT_6 = DateTimeFormatter.ofPattern("H:m:ss");
    private static DateTimeFormatter TIME_FORMAT_7 = DateTimeFormatter.ofPattern("H:m:s");
    private static DateTimeFormatter TIME_FORMAT_8 = DateTimeFormatter.ofPattern("HH:mm");
    private static DateTimeFormatter TIME_FORMAT_9 = DateTimeFormatter.ofPattern("HH:m");
    private static DateTimeFormatter TIME_FORMAT_10 = DateTimeFormatter.ofPattern("H:mm");
    private static DateTimeFormatter TIME_FORMAT_11 = DateTimeFormatter.ofPattern("H:m");

    private CacheDateTimeConvert() {

    }

    @ScalarFunction("cache_date_convert")
    @Description("convert cache date to standard date format.")
    @SqlType(StandardTypes.VARCHAR)
    @SqlNullable
    public static Slice cache_date_convert(@SqlType(StandardTypes.VARCHAR) Slice cacheDateStr) {
        if (null == cacheDateStr) {
            return null;
        }

        String cacheDate = cacheDateStr.toStringUtf8();
        LocalDate beginDate = LocalDate.of(1840, 12, 31);
        try {
            long cacheDateValue = Long.parseLong(cacheDate);
            return Slices.utf8Slice(beginDate.plusDays(cacheDateValue).format(DATE_FORMAT));
        } catch (Exception e) {
            return null;
        }
    }

    @ScalarFunction("cache_time_convert")
    @Description("convert cache time to standard time format.")
    @SqlType(StandardTypes.VARCHAR)
    @SqlNullable
    public static Slice cache_time_convert(@SqlType(StandardTypes.VARCHAR) Slice cacheTimeStr) {
        if (null == cacheTimeStr) {
            return null;
        }

        String cacheTime = cacheTimeStr.toStringUtf8();
        try {
            int cacheTimeValue = Integer.parseInt(cacheTime);
            return Slices.utf8Slice(String.format("%02d:%02d:%02d", cacheTimeValue / 3600, (cacheTimeValue / 60) % 60,
                    cacheTimeValue % 60));
        } catch (Exception e) {
            return null;
        }
    }

    @ScalarFunction("self_date_convert")
    @Description("convert date to standard date format.")
    @SqlType(StandardTypes.VARCHAR)
    @SqlNullable
    public static Slice self_date_convert(@SqlType(StandardTypes.VARCHAR) Slice dateStr) {
        if (null == dateStr) {
            return null;
        }

        String date = dateStr.toStringUtf8();
        try {
            LocalDate localDate = LocalDate.parse(date, DATE_FORMAT_1);
            return Slices.utf8Slice(localDate.format(DATE_FORMAT));
        } catch (Exception e) {
            try {
                LocalDate localDate = LocalDate.parse(date, DATE_FORMAT_2);
                return Slices.utf8Slice(localDate.format(DATE_FORMAT));
            } catch (Exception e1) {
                try {
                    LocalDate localDate = LocalDate.parse(date, DATE_FORMAT_3);
                    return Slices.utf8Slice(localDate.format(DATE_FORMAT));
                } catch (Exception e2) {
                    try {
                        LocalDate localDate = LocalDate.parse(date, DATE_FORMAT_4);
                        return Slices.utf8Slice(localDate.format(DATE_FORMAT));
                    } catch (Exception e3) {
                        return null;
                    }
                }
            }
        }
    }

    @ScalarFunction("self_time_convert")
    @Description("convert time to standard time format.")
    @SqlType(StandardTypes.VARCHAR)
    @SqlNullable
    public static Slice self_time_convert(@SqlType(StandardTypes.VARCHAR) Slice timeStr) {
        if (null == timeStr) {
            return null;
        }

        String time = timeStr.toStringUtf8();
        try {
            LocalTime localTime = LocalTime.parse(time, TIME_FORMAT);
            return Slices.utf8Slice(localTime.format(TIME_FORMAT));
        } catch (Exception e) {
            try {
                LocalTime localTime = LocalTime.parse(time, TIME_FORMAT_1);
                return Slices.utf8Slice(localTime.format(TIME_FORMAT));
            } catch (Exception e1) {
                try {
                    LocalTime localTime = LocalTime.parse(time, TIME_FORMAT_2);
                    return Slices.utf8Slice(localTime.format(TIME_FORMAT));
                } catch (Exception e2) {
                    try {
                        LocalTime localTime = LocalTime.parse(time, TIME_FORMAT_3);
                        return Slices.utf8Slice(localTime.format(TIME_FORMAT));
                    } catch (Exception e3) {
                        try {
                            LocalTime localTime = LocalTime.parse(time, TIME_FORMAT_4);
                            return Slices.utf8Slice(localTime.format(TIME_FORMAT));
                        } catch (Exception e4) {
                            try {
                                LocalTime localTime = LocalTime.parse(time, TIME_FORMAT_5);
                                return Slices.utf8Slice(localTime.format(TIME_FORMAT));
                            } catch (Exception e5) {
                                try {
                                    LocalTime localTime = LocalTime.parse(time, TIME_FORMAT_6);
                                    return Slices.utf8Slice(localTime.format(TIME_FORMAT));
                                } catch (Exception e6) {
                                    try {
                                        LocalTime localTime = LocalTime.parse(time, TIME_FORMAT_7);
                                        return Slices.utf8Slice(localTime.format(TIME_FORMAT));
                                    } catch (Exception e7) {
                                        try {
                                            LocalTime localTime = LocalTime.parse(time, TIME_FORMAT_8);
                                            return Slices.utf8Slice(localTime.format(TIME_FORMAT));
                                        } catch (Exception e8) {
                                            try {
                                                LocalTime localTime = LocalTime.parse(time, TIME_FORMAT_9);
                                                return Slices.utf8Slice(localTime.format(TIME_FORMAT));
                                            } catch (Exception e9) {
                                                try {
                                                    LocalTime localTime = LocalTime.parse(time, TIME_FORMAT_10);
                                                    return Slices.utf8Slice(localTime.format(TIME_FORMAT));
                                                } catch (Exception e10) {
                                                    try {
                                                        LocalTime localTime = LocalTime.parse(time, TIME_FORMAT_11);
                                                        return Slices.utf8Slice(localTime.format(TIME_FORMAT));
                                                    } catch (Exception e11) {
                                                        return null;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
//        System.out.println(cache_date_convert(Slices.utf8Slice("65561")).toStringUtf8());
//        System.out.println(cache_time_convert(Slices.utf8Slice("70")).toStringUtf8());
//
//        System.out.println(self_date_convert(Slices.utf8Slice("2021.11.1")).toStringUtf8());
//        System.out.println(self_time_convert(Slices.utf8Slice("9:21")).toStringUtf8());


        String min = "α代表“领袖”，优秀（的人";
        String max = "vWF检查";
        System.out.println(Slices.utf8Slice(min).compareTo(0, min.length(), Slices.utf8Slice(max), 0, max.length()));
    }
}
